const db = require("../../../config/mysql");
const { performance } = require('perf_hooks');

// 使用Map代替对象，性能更好
const apiAccessCount = new Map();

// 配置常量
const CONFIG = {
    BATCH_INSERT_THRESHOLD: 100, // 批量插入阈值
    CLEANUP_MONTHS: 3,          // 清理多少个月前的数据
};
// 统计锁，防止重复统计
let isProcessing = false;

/**
 * 增加接口访问量统计
 * @param {string} url 接口地址
 */
const addAccessStatisticsLog = (url) => {
    // "/favicon.png" 等静态资源不需要统计
    if (url.includes('/favicon.png')) return;
    // 放行swagger
    if (url.includes('/com.chrome.devtools.json')) return;
    if (!url || typeof url !== 'string') {
        console.warn('无效的URL参数:', url);
        return;
    }
    apiAccessCount.set(url, (apiAccessCount.get(url) || 0) + 1);
    console.log(`当前统计的接口访问量: ${JSON.stringify(Array.from(apiAccessCount.entries()))}`);
    // 覆盖打印
    // process.stdout.write(`当前统计的接口访问量: ${JSON.stringify(Array.from(apiAccessCount.entries()))}                                                                                                                         \r`);
};
/**
 * 将统计数据存储到数据库
 */
const accessStatisticsFromSql = async () => {
    if (isProcessing || apiAccessCount.size === 0) return;
    isProcessing = true;
    const startTime = performance.now();
    try {
        const entries = Array.from(apiAccessCount.entries());
        const batchData = entries.map(([apiUrl, visits]) => [apiUrl, visits, new Date()]);

        // 如果数据量较大，分批处理
        if (batchData.length > CONFIG.BATCH_INSERT_THRESHOLD) {
            await processInBatches(batchData);
        } else {
            await insertBatch(batchData);
        }
        console.log(`成功统计了 ${batchData.length} 个接口的访问量，耗时: ${(performance.now() - startTime).toFixed(2)}ms`);
    } catch (error) {
        console.error('存储统计数据失败:', error);
        // 可以添加重试逻辑或错误上报
    } finally {
        apiAccessCount.clear();
        isProcessing = false;
    }
};
/**
 * 分批处理大数据量
 */
const processInBatches = async (data) => {
    const batchSize = CONFIG.BATCH_INSERT_THRESHOLD;
    for (let i = 0; i < data.length; i += batchSize) {
        const batch = data.slice(i, i + batchSize);
        await insertBatch(batch);
    }
};
/**
 * 执行批量插入
 */
const insertBatch = async (batchData) => {
    console.log(`正在插入 ${batchData} 数据`);
    const query = `
    INSERT INTO apitraffic (apiUrl, visits, recordingTime) 
    VALUES ? 
    ON DUPLICATE KEY UPDATE visits = visits + VALUES(visits)
  `;
    await db.query(query, [batchData]);
};
/**
 * 清理过期的统计数据
 */
const cleanUpOldData = async () => {
    try {
        const { affectedRows } = await db.query(`
      DELETE FROM apitraffic
      WHERE recordingTime < DATE_SUB(NOW(), INTERVAL ? MONTH)
      LIMIT 10000
    `, [CONFIG.CLEANUP_MONTHS]);

        if (affectedRows > 0) {
            console.log(`已清理 ${affectedRows} 条过期统计数据`);
        }
    } catch (error) {
        console.error('清理过期数据失败:', error);
    }
};
/**
 * 统计昨天的接口访问量并存入log_api_day表
 */
const generateDailyStatistics = async () => {
    try {
        const startTime = performance.now();

        // 查询昨天的数据并汇总
        const [results] = await db.query(`
      INSERT INTO log_api_day (apiUrl, visits, statDate)
      SELECT 
        apiUrl, 
        SUM(visits) as visits,
        DATE(DATE_SUB(NOW(), INTERVAL 1 DAY)) as statDate
      FROM apitraffic
      WHERE DATE(recordingTime) = DATE(DATE_SUB(NOW(), INTERVAL 1 DAY))
      GROUP BY apiUrl
      ON DUPLICATE KEY UPDATE visits = VALUES(visits)
    `);

        console.log(`成功生成昨日接口统计，耗时: ${(performance.now() - startTime).toFixed(2)}ms`);

        // 返回影响的行数
        return results.affectedRows;
    } catch (error) {
        console.error('生成每日统计失败:', error);
        throw error;
    }
};

/**
 * 统计上个月的接口访问量并存入log_api_month表
 */
const generateMonthlyStatistics = async () => {
    try {
        const startTime = performance.now();

        // 查询上个月的数据并汇总
        const [results] = await db.query(`
      INSERT INTO log_api_month (apiUrl, visits, statMonth)
      SELECT 
        apiUrl, 
        SUM(visits) as visits,
        DATE_FORMAT(DATE_SUB(NOW(), INTERVAL 1 MONTH), '%Y-%m') as statMonth
      FROM apitraffic
      WHERE DATE_FORMAT(recordingTime, '%Y-%m') = DATE_FORMAT(DATE_SUB(NOW(), INTERVAL 1 MONTH), '%Y-%m')
      GROUP BY apiUrl
      ON DUPLICATE KEY UPDATE visits = VALUES(visits)
    `);

        console.log(`成功生成上月接口统计，耗时: ${(performance.now() - startTime).toFixed(2)}ms`);

        // 返回影响的行数
        return results.affectedRows;
    } catch (error) {
        console.error('生成月度统计失败:', error);
        throw error;
    }
};
module.exports = {
    addAccessStatisticsLog,// 增加接口访问量统计
    accessStatisticsFromSql,// 将统计数据存储到数据库
    cleanUpOldData,// 清理过期的统计数据
    generateDailyStatistics,// 统计昨天的接口访问量并存入log_api_day表
    generateMonthlyStatistics// 统计上个月的接口访问量并存入log_api_month表
};